package com.info.zhiduoduo.admin.service;

import com.baomidou.mybatisplus.mapper.Condition;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.info.zhiduoduo.admin.model.formbean.crowdsourcedeposit.ListDepositFormBean;
import com.info.zhiduoduo.admin.model.formbean.crowdsourcedeposit.SettleDepositFormBean;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.company.CompanyAccountFlowAccountType;
import com.info.zhiduoduo.common.constants.company.CompanyAccountFlowBizType;
import com.info.zhiduoduo.common.constants.crowdsource.CrowdsourceDepositState;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.formbean.BaseSimpleFormBean;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.core.service.common.BaseService;
import com.info.zhiduoduo.repository.dto.crowdsource.CrowdsourceMonthlyDepositDto;
import com.info.zhiduoduo.repository.entity.company.CompanyAccount;
import com.info.zhiduoduo.repository.entity.company.CompanyAccountflow;
import com.info.zhiduoduo.repository.entity.company.CompanyPayment;
import com.info.zhiduoduo.repository.entity.company.CrowdsourceMonthlyDepositRecord;
import com.info.zhiduoduo.repository.mapper.company.CompanyAccountMapper;
import com.info.zhiduoduo.repository.mapper.company.CompanyAccountflowMapper;
import com.info.zhiduoduo.repository.mapper.company.CompanyPaymentMapper;
import com.info.zhiduoduo.repository.mapper.company.CrowdsourceMonthlyDepositRecordMapper;
import com.info.zhiduoduo.repository.mapper.crowdsource.CrowdsourceProjectMapper;

import org.hibernate.validator.constraints.Range;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.validation.Valid;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CrowdsourceDepositService extends BaseService {

	@Resource
	CrowdsourceMonthlyDepositRecordMapper crowdsourceMonthlyDepositRecordMapper;
	@Resource
	CompanyPaymentMapper companyPaymentMapper;
	@Resource
	CompanyAccountflowMapper companyAccountflowMapper;
	@Resource
	CrowdsourceProjectMapper crowdsourceProjectMapper;

	public SmartResult<CrowdsourceMonthlyDepositDto> list(BaseSimpleFormBean<ListDepositFormBean> formBean) {
		@Valid ListDepositFormBean reqdata = formBean.getReqdata();
		String name = reqdata.getName();
		@Range(max = 2) int state = reqdata.getState();
		Date startDate = reqdata.getStartDate();
		Date endDate = reqdata.getEndDate();
		Page<CrowdsourceMonthlyDepositDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<CrowdsourceMonthlyDepositDto> list = crowdsourceMonthlyDepositRecordMapper.listByDate(name, state, startDate, endDate);
		return smartResult(list, page.getTotal(), page.getPages(), page.getPageNum());
	}

	@Transactional
	public SmartResult settleDeposit(BaseSimpleFormBean<SettleDepositFormBean> formBean) {
		int adminid = formBean.getUserid();
		@Valid SettleDepositFormBean reqdata = formBean.getReqdata();
		int id = reqdata.getId();
		BigDecimal actualDeposit = reqdata.getActualDeposit();
		CrowdsourceMonthlyDepositRecord record = new CrowdsourceMonthlyDepositRecord().selectById(id);
		Asserts.notNull(record, StatusMsg.StatusMsg_641);
		Asserts.isTrue(NumberUtil.equals(record.getState(), CrowdsourceDepositState.CREATED), StatusMsg.StatusMsg_642);

		//1、选择线下返回还是线上返回，线下就不用插入企业流水了
		//2、如果是线下返回需要选择支付方式
		if (reqdata.getIsOnline() == 0) { //线上
			Integer payId = reqdata.getPayId();
			CompanyPayment companyPayment = companyPaymentMapper.getCompanyPayment(record.getCompid(), reqdata.getPayId());
			if(companyPayment == null){
				// 新建账户余额
				companyPayment = new CompanyPayment().setBalance(BigDecimal.ZERO)
													 .setFrozenBalance(BigDecimal.ZERO)
													 .setCompid(record.getCompid())
													 .setPayId(payId);
				companyPayment.insert();

			}
			// 修改企业余额
			BigDecimal beforeBalance = companyPayment.getBalance();
			BigDecimal currBalance = companyPayment.getBalance().add(actualDeposit);
			companyPayment.setBalance(currBalance).updateById();

			// 增加企业流水
			new CompanyAccountflow().setCompid(record.getCompid())
									.setFlowname(DateUtil.getString(record.getMonth(), DateUtil.FORMAT_STYLE_12) + "返还企业保证金")
									.setFlowtype(1)
									.setBizid(record.getId())
									.setBizType(CompanyAccountFlowBizType.RETURN_DEPOSIT)
									.setAccountType(CompanyAccountFlowAccountType.ZDD_UNIFY)
									.setFlowAmount(actualDeposit)
									.setBeforeBalance(beforeBalance)
									.setCurrBalance(currBalance)
									.setBeforeFrozenBalance(companyPayment.getFrozenBalance())
									.setCurrFrozenBalance(companyPayment.getFrozenBalance())
									.setPayId(payId)
									.insert();

		}

		// 返还保证金，修改项目中保证金返还状态
		Date month = record.getMonth();
		Date startDate = DateUtil.getDateMonthBeginDate(month);
		Date endDate = DateUtil.getDateMonthEndDate(month);
		crowdsourceProjectMapper.updateProjectDepositState(record.getCompid(), startDate, endDate);

		// 修改保证金返还记录
		record.setActualReturnDeposit(actualDeposit)
			  .setIsOnline(record.getIsOnline())
			  .setState(CrowdsourceDepositState.SETTLED)
			  .setReturnTime(new Date())
			  .setAdminid(adminid)
			  .updateById();
		return SmartResult.success();
	}

	public void recordCompanyCrowdsourceDeposit() {
		recordCompanyCrowdsourceDeposit(null);
	}

	public void recordCompanyCrowdsourceDeposit(Date month) {
		//如果时是当月1号
		Date beginDate = null;
		Date endDate = null;
		if (DateUtil.getNowDay() == 1) {
			beginDate = DateUtil.getLastMonthBeginDate();
			endDate = DateUtil.getLastMonthEndDate();
		} else {
			beginDate = DateUtil.getThisMonthBeginDate();
			endDate = DateUtil.getThisMonthEndDate();
		}
		if (month != null) {
			beginDate = DateUtil.getStartDayOfMonth(month);
			endDate = DateUtil.getEndDayOfMonth(month);
		}
		List<CrowdsourceMonthlyDepositRecord> list = crowdsourceProjectMapper.sumTotalProjectAmountGroupByCompid(beginDate, endDate);
		log.info("计算企业每月保证金------总条数{}", list.size());
		for (CrowdsourceMonthlyDepositRecord record : list) {
			calcCompanyCrowdsourceDeposit(record);
		}
	}

	private void calcCompanyCrowdsourceDeposit(CrowdsourceMonthlyDepositRecord record) {
		//新增或修改保证金数据
		CrowdsourceMonthlyDepositRecord depositRecord = crowdsourceMonthlyDepositRecordMapper.selectMonthData(record.getCompid(),
				record.getMonth());
		if (depositRecord != null) {
			depositRecord.setProjectAmount(record.getProjectAmount())
					.setProjectTaxFee(record.getProjectTaxFee())
					.setShouldReturnDeposit(record.getShouldReturnDeposit())
					.setActualDepositRate(record.getDepositRate())
					.updateById();
		} else {
			record.setIsOnline(0).setActualDepositRate(record.getDepositRate()).setState(CrowdsourceDepositState.CREATED);
			record.insert();
		}
	}
}
